package com.zhuiyun.project.api.system.login.controller;

import com.zhuiyun.project.api.frontuser.entity.FrontUser;
import com.zhuiyun.project.api.frontuser.service.FrontUserService;
import com.zhuiyun.project.api.system.login.entity.WeChatModel;
import com.zhuiyun.project.api.system.login.service.impl.FrontUserInfoService;
import com.zhuiyun.project.api.system.login.service.impl.SysPermissionService;
import com.zhuiyun.project.api.system.menu.entity.SysMenu;
import com.zhuiyun.project.api.system.menu.service.SysMenuService;
import com.zhuiyun.project.api.system.user.entity.SysUser;
import com.zhuiyun.project.common.errorCode.CommonException;
import com.zhuiyun.project.common.errorCode.EmErrorCode;
import com.zhuiyun.project.common.response.CommonResult;
import com.zhuiyun.project.security.jwt.JWTConfig;
import com.zhuiyun.project.security.jwt.JWTUtils;
import com.zhuiyun.project.utils.RedisUtil;
import com.zhuiyun.project.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * @ClassName SysLoginController
 * @Description TODO
 * @Author lzy
 * @Date 2023/6/16 13:55
 **/
@RestController
public class SysLoginController {
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    private FrontUserService frontUserService;
    @Autowired
    private SysMenuService menuService;
    @Autowired
    BCryptPasswordEncoder encoder;
    @Autowired
    public FrontUserInfoService frontUserInfoService;
    @Resource
    BCryptPasswordEncoder passwordEncoder;
    /**
     * @return
     * @Author LYX
     * @Description
     * @Date 2024/2/26 15:47
     * weChatModel 获取临时凭证code
     */
    @PostMapping("wxLogin")
    public CommonResult wxlogin(@RequestBody WeChatModel weChatModel, HttpServletResponse response) {
        // 检查登录
        FrontUser frontUsers = frontUserInfoService.checkLogin(weChatModel.getCode());
        // resultMap大于1为通过，业务层判断正确后返回用户信息和token，所以应该size为2才正确。
        if (frontUsers!=null){
            // 生成token
            String token = JWTUtils.createAccessToken(frontUsers);
            // 设置token过期时间
            RedisUtil.set(token,frontUsers, JWTConfig.expiration);
            // 将token添加入响应头以及返回用户信息
            response.setHeader(JWTUtils.header,token);
            return CommonResult.ok(token);
        }else{
            // 当返回map的size为1时，即为报错信息
            return CommonResult.error(500,"用户不存在，请注册");
        }
    }
    /**
     * @return
     * @Author LYX
     * @Description
     * @Date 2024/3/8 15:47
     * weChatModel 微信注册
     */
    @PostMapping("WXRegistration")
    public CommonResult WXRegistration(@RequestBody WeChatModel weChatModel) throws CommonException {
        return frontUserInfoService.wxRegistration(weChatModel.getCode());
    }
    /**
     * @return
     * @Author LYX
     * @Description
     * @Date 2024/2/26 15:47
     * weChatModel 获取临时凭证code
     */
    @PostMapping("wxBindAccount")
    public CommonResult wxBindAccount(@RequestBody WeChatModel weChatModel) {
        // 检查登录
        String jg = frontUserInfoService.checkLogin2(weChatModel.getCode());
        // 判断微信是否绑定过账户
        //没有绑定过，值就是openid
        //绑定过，值就是null
        if (jg!=null){
            int id=weChatModel.getId();
            Boolean outcome=frontUserService.updateOpenid(id,jg);
            if (outcome){
                FrontUser frontUsers = frontUserService.getFrontUserByOpenId(jg);
                String token = JWTUtils.createAccessToken(frontUsers);
                // 更新redis
                RedisUtil.set(token,frontUsers, JWTConfig.expiration);
                // 修改成功
                return CommonResult.ok("微信绑定成功");
            }else{
                // 修改失败
                return CommonResult.ok("微信绑定失败");
            }
        }else{
            return CommonResult.ok("当前微信号已绑定过账户,不可重复绑定");
        }
    }

    /**
     * @return
     * @Author LYX
     * @Description
     * @Date 2024/1/3 15:47
     */
    @PostMapping("zhanghulogin")
    public CommonResult zhanghulogin(@RequestBody FrontUser frontUser) {
        FrontUser frontUsers =frontUserService.getFrontUserByUserAccount(frontUser.getUserAccount());
        if(frontUsers==null){
            //提示报错用户不存在
            return CommonResult.ok(EmErrorCode.USER_NOT_EXIST);
        }
        boolean matches = passwordEncoder.matches(frontUser.getUserPassword(),frontUsers.getUserPassword());
        if(matches||frontUser.getUserPassword().equals(frontUsers.getUserPassword())){
            // 生成token
            String token = JWTUtils.createAccessToken(frontUsers);
            // 设置token过期时间,将token 放入redis中
            RedisUtil.set(token,frontUsers, JWTConfig.expiration);
            return CommonResult.ok(token);
        }else {
            //提示报错用户名或密码错误
            return CommonResult.ok(EmErrorCode.USER_PASSWORD_ERROR);
        }
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public CommonResult getInfo() throws IOException {
        SysUser user = (SysUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        HashMap<Object, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("roles", roles);
        map.put("permissions", permissions);
        return CommonResult.ok(map);
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public CommonResult getRouters() {
        Integer userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return CommonResult.ok(menuService.buildMenus(menus));
    }

}
